iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 5
1

一路上感謝各位讀者們的支持和回饋。
本 30 天系列文目前已經將篇幅重新整理、編纂成冊。
《JavaScript 概念三明治》在天瓏書局上架囉!
喜歡這個系列,想閱讀更詳細原理說明的讀者可以參考:
https://www.tenlong.com.tw/products/9789864347575

在上一章我們針對什麼是範疇 ,以及兩種不同的範疇做了說明,而如果 JS 在範疇內找不到某變數, 就會向外尋找。在這章節我會針對這個預設行為做比較詳細的說明。

Outline

  • 複習一下執行堆疊
  • 範疇鍊:攸關語彙環境

複習一下執行堆疊

這邊我直接上一個稍微複雜點的範例:

https://ithelp.ithome.com.tw/upload/images/20190920/20106580DFIazio5b0.jpg

我們從全域呼叫了 a 函式,產生了 a 執行環境,後又在 a 函式裡面呼叫了 c 函式,最後在裡面才呼叫了 b 函式 ( a → c → b),因此會有一連串的執行環境依序被產生,而行程執行堆疊。把概念套用到我們之前的模型,(你現在應該可以想像了),大概長這樣,:

https://ithelp.ithome.com.tw/upload/images/20190920/20106580ZsgqISboCb.jpg

範疇鍊:攸關語彙環境

在 function 產生的執行環境內一但找不到某個變數,預設會向外部環境尋找看看該變數有沒有在外面被宣告,這裡的「外部環境」是什麼呢?有人可能會很直覺的看向上面的執行堆疊圖,然後說這個外部環境是上一個執行環境的堆疊。

其實並不是這樣,這邊有一個很重要的觀念,也是今天的重點: JavaScript 會根據前面提過的「語彙環境」,也就是程式碼的實際位置(全域 或是 函式內),來決定要往哪裡去尋找這個找不到的變數。

https://ithelp.ithome.com.tw/upload/images/20190920/20106580ESRoZSR8nC.jpg

因為 函式 c 在 函式 a 的裡面,因此我們可以說 c函式的外部語彙環境在 a 函式,以此類推,b 函式的外部語彙環境則是全域環境,因此當我們在 b 函式裡面想要呼叫 c 函式內部的變數的時候,理所當然是找不到的(因為 JS 會從 b 函式的執行環境往全域尋找)。 最後附上對應的程式碼圖來驗證上面的說明:

https://ithelp.ithome.com.tw/upload/images/20190920/20106580MO0e1MCr8K.jpg

今天的主題其實就是上述的觀念,所以只要能夠了解執行環境與語彙環境的差異,就能知道什麼是「 Scope Chain ( 範疇鍊)」了,當執行環境往外部環境尋找變數,仍然找不到的時候,就會不斷往更外一層的語彙環境去尋找,直到找到這個變數或是找到全域環境為止(如果到全域仍然找不到,就會跳錯誤)。

例如在這個範例裡面的 c 函式,如果想要取用全域變數的時候,會先往外( a 函式)尋找,發現找不到,才又往全域環境尋找(可往上參考語彙環境堆疊圖)。這一連串的查找動作所產生的物理位置的裡外關係(而不是執行環境產生的先後順序),就是 Scope Chain 。


上一篇
JS 原力覺醒 Day04 - Function Scope / Block Scope
下一篇
JS 原力覺醒 Day06 - 提升 Hoisting
系列文
JavaScript 原力覺醒 - 成為絕地武士之路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

1
yanzhong
iT邦新手 4 級 ‧ 2020-12-08 16:41:30

超級有用的!!!

Spark iT邦新手 5 級 ‧ 2021-09-04 22:49:23 檢舉

謝謝啦,真的有幫助到你就好了!

我要留言

立即登入留言